package com.dog.basics.netty.handel;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.dog.basics.bean.model.mtkj.MtDeviceLock;
import com.dog.basics.common.util.SpringContextUtils;
import com.dog.basics.netty.business.BusinessFactory;
import com.dog.basics.netty.kit.HeartBeatHandler;
import com.dog.basics.netty.kit.ServerHeartBeatHandlerImpl;
import com.dog.basics.netty.pojo.BusinessBean;
import com.dog.basics.netty.protobuf.dto.DogNewsContentDto;
import com.dog.basics.netty.util.SessionSocketHolder;
import com.dog.basics.service.mtkj.IMtDeviceLockService;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;

/**
 * @program:  通讯协议消息
 * @description:
 * @author: Guo
 * @create: 2019-08-27 11:45
 **/
@Log4j2
@AllArgsConstructor
public class DogNewServerHandle extends SimpleChannelInboundHandler<DogNewsContentDto.Message> {


    /**
     * 取消绑定
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //可能出现业务判断离线后再次触发 channelInactive
        Long equipmentId = SessionSocketHolder.getSession(ctx.channel().id().asLongText());
        if (ObjectUtil.isNotNull(equipmentId)) {
            log.info("[{}]触发 channelInactive 掉线 - 删除信息!", equipmentId);
            SessionSocketHolder.logu(ctx.channel().id().asLongText());
            //设备下线
            MtDeviceLock deviceLock = new MtDeviceLock();
            deviceLock.setId(equipmentId);
            deviceLock.setDevOnlineState(0);
            deviceLock.setUpdateTime(DateUtil.currentSeconds());
            SpringContextUtils.getBean(IMtDeviceLockService.class).updateById(deviceLock);
            //设备下线
            ctx.channel().close();
        }
    }

    /**
     * 活跃的
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
    }

    /**
     * 定时检测客户端是否存在
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            if (idleStateEvent.state() == IdleState.READER_IDLE) {
                log.info("定时检测客户端是否存活");
                HeartBeatHandler heartBeatHandler = SpringContextUtils.getBean(ServerHeartBeatHandlerImpl.class);
                heartBeatHandler.process(ctx);
            }
        }
        super.userEventTriggered(ctx, evt);
    }


    /**
     * 接受到消息
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DogNewsContentDto.Message msg) {
        BusinessFactory.goOn(BusinessBean.builder().ctx(ctx).msg(msg).build());
    }

    
    /**
     * 异常机制处理
     * @param ctx
     * @param cause
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.info("异常出现:{}", cause.getMessage());
    }
}
